package com.bq.server.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import com.bq.server.base.BaseService;
import com.bq.server.core.mapper.CadreDeptMapper;
import com.bq.server.core.mapper.CadreRelationsInfoMapper;
import com.bq.server.core.mapper.DepartmentMapper;
import com.bq.server.core.model.CadreAppointInfo;
import com.bq.server.core.model.CadreDept;
import com.bq.server.core.model.CadreRelationsInfo;
import com.bq.server.core.model.Department;
import com.bq.server.core.vo.request.AdjustDeptRequest;
import com.bq.server.core.vo.request.CadreAppointInfoRequest;
import com.bq.server.core.vo.request.CadreRelationsInfoRequest;
import com.bq.server.exception.BusinessException;
import com.bq.server.properties.MybatisPlusSecurityProperties;
import com.bq.server.service.CadreRelationsInfoService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.model.PicturesTable;
import org.apache.poi.hwpf.usermodel.*;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.bq.server.core.mapper.CadreAppointInfoMapper;
import com.bq.server.service.CadreAppointInfoService;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * @author shchen
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class CadreAppointInfoServiceImpl extends BaseService<CadreAppointInfoMapper, CadreAppointInfo> implements CadreAppointInfoService {

    private final MybatisPlusSecurityProperties securityProperties;

    private static final String APPROVE_STR = "（盖章）年月日";

    private final CadreAppointInfoMapper cadreAppointInfoMapper;

    private final CadreRelationsInfoMapper cadreRelationsInfoMapper;

    private final CadreDeptMapper cadreDeptMapper;

    private final DepartmentMapper departmentMapper;

    private final CadreRelationsInfoService cadreRelationsInfoService;

    @Override
    public void create(CadreAppointInfoRequest request) {
        CadreAppointInfo cadreAppointInfo = new CadreAppointInfo();
        BeanUtil.copyProperties(request, cadreAppointInfo);
        //添加干部信息
        cadreAppointInfoMapper.insert(cadreAppointInfo);
        //保存干部社会关系信息
        cadreRelationsInfoService.saveRelations(request.getRelationsList(), cadreAppointInfo.getId());

        //保存部门人员关系
        CadreDept cadreDept = new CadreDept();
        cadreDept.setDeptId(request.getDeptId());
        cadreDept.setCadreId(cadreAppointInfo.getId());
        cadreDeptMapper.insert(cadreDept);
    }

    @Override
    public void adjustDept(AdjustDeptRequest request) {
        log.info("调整部门数据: 干部id:{},部门id:{}", request.getCadreId(), request.getDeptId());

        CadreAppointInfo cadreAppointInfo = cadreAppointInfoMapper.findInfoById(request.getCadreId());
        BusinessException.Assert.isFalse(Objects.isNull(cadreAppointInfo), "干部人员信息不存在");
        Department department = departmentMapper.findInfoById(request.getDeptId());
        BusinessException.Assert.isFalse(Objects.isNull(department), "部门信息不存在");

        //删除部门干部关系
        cadreDeptMapper.deleteByCadreId(request.getCadreId());
        insertCadreDept(department, request.getCadreId());
    }

    /**
     * 保存部门与员工的关系
     *
     * @param department 部门信息
     * @param cadreId    用户id
     */
    public void insertCadreDept(Department department, Long cadreId) {
        CadreDept cadreDept = new CadreDept();
        cadreDept.setCadreId(cadreId);
        cadreDept.setDeptId(department.getId());
        cadreDeptMapper.insert(cadreDept);
    }

    @Override
    public CadreAppointInfo info(Long cadreId) {
        CadreAppointInfo info = cadreAppointInfoMapper.findInfoById(cadreId);
        BusinessException.Assert.isFalse(Objects.isNull(info), "干部人员信息不存在");

        List<CadreRelationsInfo> relationsInfos = cadreRelationsInfoMapper.findListByCadreId(cadreId);
        if (CollUtil.isEmpty(relationsInfos)) {
            ArrayList<CadreRelationsInfo> objects = new ArrayList<>();
            objects.add(new CadreRelationsInfo());
            info.setRelationsList(objects);
        } else {
            info.setRelationsList(relationsInfos);
        }
        return info;
    }

    @Override
    public void remove(Long id) {
        cadreAppointInfoMapper.deleteById(id);
    }

    @Override
    public void updateById(Long id, CadreAppointInfoRequest request) {
        CadreAppointInfo info = cadreAppointInfoMapper.findInfoById(id);
        BusinessException.Assert.isFalse(Objects.isNull(info), "干部人员信息不存在");
        BeanUtil.copyProperties(request, info);
        cadreAppointInfoMapper.updateById(info);
        if (CollUtil.isNotEmpty(request.getRelationsList())) {
            cadreRelationsInfoMapper.deleteByCadreId(info.getId());
            cadreRelationsInfoService.saveRelations(request.getRelationsList(), info.getId());
        }
    }

    @Override
    public void importWord(MultipartFile file, Long deptId) {
        String textFileName = file.getOriginalFilename();
        try {
            if (textFileName.toLowerCase().endsWith("doc")) {
                readDoc(file.getInputStream(), deptId);
            } else if (textFileName.toLowerCase().endsWith("docx")) {
                readDocx(file.getInputStream(), deptId);
            } else {
                throw BusinessException.of(1, "文件格式错误");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            throw BusinessException.of(1, "文件导入错误");
        }
    }


    public void readDoc(InputStream in, Long deptId) throws IOException {
        HWPFDocument doc = new HWPFDocument(in);
        PicturesTable picturesTable = doc.getPicturesTable();
        List<Picture> allPictures = picturesTable.getAllPictures();
        Assert.isFalse(allPictures.size() > 1, "上传文档中图片过多");
        Assert.isFalse(allPictures.isEmpty(), "上传文档中没有图片信息");
        byte[] data = allPictures.get(0).getRawContent();
        String oriFileName = System.currentTimeMillis() + ".png";
        FileUtil.writeBytes(data, securityProperties.getFolder() + oriFileName);
        String uploadImg = "/img/" + oriFileName;

        Range range = doc.getOverallRange();
        TableIterator it = new TableIterator(range);
        List<CadreRelationsInfoRequest> cadreRelationsInfoList = new ArrayList<>();
        Map<String, Object> cadreInfoMap = new HashMap<>();
        // 过滤前面不需要的表格
        if (it.hasNext()) {
            it.next();
        }
        // 得到需要的第二个表格，业务数据
        while (it.hasNext()) {
            Table xwpfTable = it.next();
            // 读取每一行
            boolean addNum = true;
            for (int i = 0; i < xwpfTable.numRows(); i++) {
                TableRow row = xwpfTable.getRow(i);
                if (row != null) {
                    log.info("第{}行，列数={}", i + 1, row.numCells());
                    if (row.numCells() == 1) {
                        continue;
                    }
                    //家庭成员相关列
                    if (row.numCells() == 6) {
                        for (int j = 0; j < row.numCells(); j++) {
                            TableCell cell = row.getCell(j);
                            if (cell != null) {
                                String cellText = cell.text().replaceAll("\\s*", "").trim();
                                log.info(cellText);
                            }
                        }
                        String s = row.getCell(0).text().replaceAll("\\s*", "").trim();
                        if ("家庭主要成员及重要社会关系".equals(s)) {
                            continue;
                        }
                        String text = row.getCell(1).text().trim();
                        if ("".equals(text)) {
                            continue;
                        }
                        CadreRelationsInfoRequest cadreRelationsInfo = handleCell6(row);
                        cadreRelationsInfoList.add(cadreRelationsInfo);
                    } else {
                        //根据模板读取需要的数据单元格，从第一列开始读取
                        for (int j = 0; j < row.numCells(); j++) {
                            TableCell cell = row.getCell(j);
                            if (cell != null) {
                                String cellText = cell.text().replaceAll("\\s*", "").trim();
                                log.info(cellText);
                                if ("姓名".equals(cellText)) {
                                    String name = row.getCell(j + 1).text().replaceAll("\\s*", "").trim();
                                    cadreInfoMap.put("name", name);
                                } else if ("性别".equals(cellText)) {
                                    String sex = row.getCell(j + 1).text().replaceAll("\\s*", "").trim();
                                    cadreInfoMap.put("gender", "男".equals(sex) ? 1 : 2);
                                } else if ("入党时间".equals(cellText)) {
                                    String joinPartyTime = row.getCell(j + 1).text().replaceAll("\\s*", "").trim();
                                    cadreInfoMap.put("joinPartyTime", joinPartyTime);
                                } else if ("参加工作时间".equals(cellText)) {
                                    String inWorkTime = row.getCell(j + 1).text().replaceAll("\\s*", "").trim();
                                    cadreInfoMap.put("inWorkTime", inWorkTime);
                                } else if ("毕业院校系及专业".equals(cellText)) {
                                    if (addNum) {
                                        cadreInfoMap.put("graduationSchool", row.getCell(j + 1).text().trim());
                                        addNum = false;
                                    } else {
                                        cadreInfoMap.put("graduationSchoolJob", row.getCell(j + 1).text().trim());
                                    }
                                } else if ("审意批机关见".equals(cellText)) {
                                    String approveTime = row.getCell(j + 1).text().replaceAll("\\s*", "").trim();
                                    if (!APPROVE_STR.equals(approveTime)) {
                                        String[] split = APPROVE_STR.split("（盖章）");
                                        cadreInfoMap.put("approveTime", split[1]);
                                    }
                                } else if ("行任政免机意关见".equals(cellText)) {
                                    String administrationApproveTime = row.getCell(j + 1).text().replaceAll("\\s*", "").trim();
                                    if (!APPROVE_STR.equals(administrationApproveTime)) {
                                        String[] split = APPROVE_STR.split("（盖章）");
                                        cadreInfoMap.put("administrationApproveTime", split[1]);
                                    }
                                } else if (propertyMap.containsKey(cellText)) {
                                    cadreInfoMap.put(propertyMap.get(cellText), row.getCell(j + 1).text().trim());
                                }
                            }
                        }
                    }
                }
            }
        }
        log.info(" 干部信息={}", cadreInfoMap);
        log.info(" 干部家庭成员信息={}", cadreRelationsInfoList);
        CadreAppointInfoRequest cadreAppointInfoRequest = BeanUtil.fillBeanWithMap(cadreInfoMap, new CadreAppointInfoRequest(), true);
        cadreAppointInfoRequest.setPhoto(uploadImg);
        cadreAppointInfoRequest.setRelationsList(cadreRelationsInfoList);
        cadreAppointInfoRequest.setDeptId(deptId);
        this.create(cadreAppointInfoRequest);
    }


    public void readDocx(InputStream in, Long deptId) throws IOException {
        XWPFDocument doc = new XWPFDocument(in);
        List<XWPFPictureData> allPictures = doc.getAllPictures();
        Assert.isFalse(allPictures.size() > 1, "上传文档中图片过多");
        byte[] data = allPictures.get(0).getData();
        String fileName = allPictures.get(0).getFileName();
        String oriFileName = System.currentTimeMillis() + fileName;
        FileUtil.writeBytes(data, securityProperties.getFolder() + oriFileName);
        String uploadImg = "/img/" + oriFileName;

        Iterator<XWPFTable> it = doc.getTablesIterator();
        List<CadreRelationsInfoRequest> cadreRelationsInfoList = new ArrayList<>();
        Map<String, Object> cadreInfoMap = new HashMap<>();
        // 过滤前面不需要的表格
        if (it.hasNext()) {
            it.next();
        }
        // 得到需要的第二个表格，业务数据
        while (it.hasNext()) {
            XWPFTable xwpfTable = it.next();
            // 读取每一行
            boolean addNum = true;
            for (int i = 0; i < xwpfTable.getRows().size(); i++) {
                XWPFTableRow row = xwpfTable.getRow(i);
                if (row != null) {
                    log.info("第{}行，列数={}", i + 1, row.getTableCells().size());
                    //家庭成员相关列
                    if (row.getTableCells().size() == 6) {
                        if ("家庭主要成员及重要社会关系".equals(row.getTableCells().get(0).getText().replaceAll("\\s*", ""))) {
                            continue;
                        }
                        if ("".equals(row.getCell(1).getText())) {
                            continue;
                        }
                        CadreRelationsInfoRequest cadreRelationsInfo = handleDockCell6(row);
                        cadreRelationsInfoList.add(cadreRelationsInfo);
                    } else {
                        //根据模板读取需要的数据单元格，从第一列开始读取
                        for (int j = 0; j < row.getTableCells().size(); j++) {
                            XWPFTableCell cell = row.getCell(j);
                            if (cell != null) {
                                String cellText = cell.getText().replaceAll("\\s*", "");
                                log.info(cellText);
                                if ("姓名".equals(cellText)) {
                                    String name = row.getCell(j + 1).getText().replaceAll("\\s*", "");
                                    cadreInfoMap.put("name", name);
                                } else if ("性别".equals(cellText)) {
                                    String sex = row.getCell(j + 1).getText().replaceAll("\\s*", "");
                                    cadreInfoMap.put("gender", "男".equals(sex) ? 1 : 2);
                                } else if ("入党时间".equals(cellText)) {
                                    String joinPartyTime = row.getCell(j + 1).getText().replaceAll("\\s*", "");
                                    cadreInfoMap.put("joinPartyTime", joinPartyTime);
                                } else if ("参加工作时间".equals(cellText)) {
                                    String inWorkTime = row.getCell(j + 1).getText().replaceAll("\\s*", "");
                                    cadreInfoMap.put("inWorkTime", inWorkTime);
                                } else if ("毕业院校系及专业".equals(cellText)) {
                                    if (addNum) {
                                        cadreInfoMap.put("graduationSchool", row.getCell(j + 1).getText());
                                        addNum = false;
                                    } else {
                                        cadreInfoMap.put("graduationSchoolJob", row.getCell(j + 1).getText());
                                    }
                                } else if ("审意批机关见".equals(cellText)) {
                                    String approveTime = row.getCell(j + 1).getText().replaceAll("\\s*", "");
                                    if (!APPROVE_STR.equals(approveTime)) {
                                        String[] split = APPROVE_STR.split("（盖章）");
                                        cadreInfoMap.put("approveTime", split[1]);
                                    }
                                } else if ("行任政免机意关见".equals(cellText)) {
                                    String administrationApproveTime = row.getCell(j + 1).getText().replaceAll("\\s*", "");
                                    if (!APPROVE_STR.equals(administrationApproveTime)) {
                                        String[] split = APPROVE_STR.split("（盖章）");
                                        cadreInfoMap.put("administrationApproveTime", split[1]);
                                    }
                                } else if (propertyMap.containsKey(cellText)) {
                                    cadreInfoMap.put(propertyMap.get(cellText), row.getCell(j + 1).getText());
                                }
                            }
                        }
                    }
                }
            }
        }
        log.info(" 干部信息={}", cadreInfoMap);
        log.info(" 干部家庭成员信息={}", cadreRelationsInfoList);
        CadreAppointInfoRequest cadreAppointInfoRequest = BeanUtil.fillBeanWithMap(cadreInfoMap, new CadreAppointInfoRequest(), true);
        cadreAppointInfoRequest.setPhoto(uploadImg);
        cadreAppointInfoRequest.setRelationsList(cadreRelationsInfoList);
        cadreAppointInfoRequest.setDeptId(deptId);
        this.create(cadreAppointInfoRequest);
    }

    private CadreRelationsInfoRequest handleCell6(TableRow row) {
        //家庭成员列第一行数据为空
        CadreRelationsInfoRequest cadreRelationsInfo = new CadreRelationsInfoRequest();
        cadreRelationsInfo.setAppellation(row.getCell(1).text().trim());
        cadreRelationsInfo.setName(row.getCell(2).text().trim());
        cadreRelationsInfo.setAge(row.getCell(3).text().trim());
        cadreRelationsInfo.setPoliticalClimate(row.getCell(4).text().trim());
        cadreRelationsInfo.setWorkUnit(row.getCell(5).text().trim());
        return cadreRelationsInfo;
    }

    private CadreRelationsInfoRequest handleDockCell6(XWPFTableRow row) {
        //家庭成员列第一行数据为空
        CadreRelationsInfoRequest cadreRelationsInfo = new CadreRelationsInfoRequest();
        cadreRelationsInfo.setAppellation(row.getCell(1).getText());
        cadreRelationsInfo.setName(row.getCell(2).getText());
        cadreRelationsInfo.setAge(row.getCell(3).getText());
        cadreRelationsInfo.setPoliticalClimate(row.getCell(4).getText());
        cadreRelationsInfo.setWorkUnit(row.getCell(5).getText());
        return cadreRelationsInfo;
    }


    static final Map<String, String> propertyMap = new HashMap<>(50);

    static {
        propertyMap.put("出生年月(岁)", "birthday");
        propertyMap.put("民族", "familyName");
        propertyMap.put("籍贯", "nativePlace");
        propertyMap.put("出生地", "birthCity");
        propertyMap.put("健康状况", "healthyStatus");
        propertyMap.put("专业技术职务", "majorSkill");
        propertyMap.put("熟悉专业有何专长", "majorKnow");
        propertyMap.put("全日制教育", "qualification");
        propertyMap.put("在职教育", "qualificationJob");
        propertyMap.put("现任职务", "currentPosition");
        propertyMap.put("拟任职务", "proposedPosition");
        propertyMap.put("拟免职务", "deposablePosition");
        propertyMap.put("简历", "resume");
        propertyMap.put("奖惩情况", "rewards");
        propertyMap.put("年核度结考果", "annualAssessment");
        propertyMap.put("任免理由", "appointReason");
        propertyMap.put("呈报单位", "reportUnit");
        propertyMap.put("审意批机关见", "approveOpinion");
        propertyMap.put("行任政免机意关见", "administrationOfficeOpinion");
    }
}





